#include "timer_rit.h"





static void stm32f4xx_rit_timer_initialize(struct tagTimerBase *pTB)
{
// 21M    
#define TIM_RIT_CLK  21000000

        TIM_TypeDef    *prStm32f4xx_RIT = (TIM_TypeDef *)(pTB->privatedata);
            
        uint16_t TIM5_PrescalerValue = 0;

    	TIM_TimeBaseInitTypeDef		TIM_TimeBaseInitStructure;
    	NVIC_InitTypeDef	NVIC_InitStructure;

    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
    	
        //   TIM5 clock : 21MHZ
    	TIM5_PrescalerValue = (uint16_t)((SystemCoreClock/2)/TIM_RIT_CLK) - 1;
    	
    	TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;
    	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    	TIM_TimeBaseInitStructure.TIM_Period = TIM_RIT_CLK/1000 - 1;     // 1ms
    	TIM_TimeBaseInitStructure.TIM_Prescaler = TIM5_PrescalerValue;
    	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    	TIM_TimeBaseInit(prStm32f4xx_RIT,&TIM_TimeBaseInitStructure);
  			
    	NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_Init(&NVIC_InitStructure);

    	TIM_ITConfig(prStm32f4xx_RIT,TIM_IT_Update,ENABLE);
    	TIM_Cmd(prStm32f4xx_RIT,ENABLE);            
	
}


struct tagTimerBase stm32f4xx_rit_timer = {		
		.jiff_l = (uint32_t *)&(TIM5->CNT),
		.initialize = &stm32f4xx_rit_timer_initialize,
		.privatedata = (void *)TIM5
};

    
void TIM5_IRQHandler (void)
{
        if(TIM_GetITStatus(TIM5, TIM_IT_Update) == SET)
        {
            TIM_ClearITPendingBit(TIM5,TIM_IT_Update);
            timer_run();
        }
}


struct tagTimerBase *pTimerBase = &stm32f4xx_rit_timer;





void Timer_Init(void)
{
		int32_t i;
		if (pTimerBase) {
				if (pTimerBase->initialize) {
						pTimerBase->initialize(pTimerBase);		
				}
				pTimerBase->jiffies = 0;
				for (i = 0; i < nlTIMERS; i++) {
						pTimerBase->timers[i].En = 0;		
				}	
		}	
}

void tmier_addr(const uint8_t n,const uint32_t delay,void (*fnct)(void *),void *parg)
{
		if (pTimerBase)
		if (n < nlTIMERS) {
				pTimerBase->timers[n].fnct = fnct;
				pTimerBase->timers[n].parg = parg;
				pTimerBase->timers[n].expires = pTimerBase->jiffies + delay;
				pTimerBase->timers[n].En = 1;		
		}		
}


void tmier_delete(const uint8_t n)
{
		if (pTimerBase)
		if (n < nlTIMERS) {
				pTimerBase->timers[n].En = 0;
				pTimerBase->timers[n].fnct = NULL;		
		}		
}

void timer_run(void)
{
		int32_t i;

		if (pTimerBase) {
				pTimerBase->jiffies ++;
				for (i = 0; i < nlTIMERS; i++) {
						if (pTimerBase->timers[i].En)
						if (pTimerBase->jiffies == pTimerBase->timers[i].expires) 
						if (pTimerBase->timers[i].fnct) {
								pTimerBase->timers[i].En = 0;
								pTimerBase->timers[i].fnct(pTimerBase->timers[i].parg);		
						}
				}
		}		
}
